package com.universe.titan.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;

import java.time.Duration;

/**问题：目前缓存管理自动更改为redisCacheManager缓存管理器，
 * 应用的redisCache是默认的RedisTemplate模板采用的数据序列化依然是Jdk的内置序列化机制。
 * 因此存入缓存的（User）数据格式都是jdk默认的序列化格式
 *
 */
/*自定义的RedisTemplate模板配置实现键值的json数据序列化*/
@Configuration
public class RedisConfig {



    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置KEY的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置VALUE的序列化
        template.setValueSerializer(jsonRedisSerializer);
        //返回
        return template;
    }

    /**自定义RedisTemplate的数据类型
     *  主要配置的就是序列化机制
     *  更改它的序列化器为Json格式的序列化机制
     */
//    @Bean
//    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
//
//        /*定义方法的返回值,泛型自动匹配，后面的可以省略*/
//        RedisTemplate<String,Object> template = new RedisTemplate<>();
//        template.setConnectionFactory(factory);
//
//        /*1.创建Jackson工具对象*/
//        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//        ObjectMapper om = new ObjectMapper();
//        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        /*2.为创建的工具对象设置Object映射*/
//        jackson2JsonRedisSerializer.setObjectMapper(om);
//
//        template.setValueSerializer(jackson2JsonRedisSerializer);
//        template.setHashValueSerializer(jackson2JsonRedisSerializer);
//
//        /*将key与hashKey设置为String的序列化方式*/
//        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//
//        template.setKeySerializer(stringRedisSerializer);
//        template.setHashKeySerializer(stringRedisSerializer);
//
//        template.afterPropertiesSet();
//        return template;
//    }
    /**自定义RedisCacheManager来实现缓存管理器
     *  RedisTemplate采用我们自己配置的Bean组件
     */
    @Bean
    public RedisCacheManager UserRedisCacheManager(RedisConnectionFactory redisConnectionFactory){
        /**对于新版本的redis而言，它的RedisCacheManager创建与旧版相比发生了一定的变化。
         *  这里定制了这个序列化格式：
         *  serializeKeysWith(RedisSerializationContext.
         *      SerializationPair.fromSerializer(new StringRedisSerializer()))
         *  serializeValuesWith(RedisSerializationContext.
         *      SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(User.class)));
         *  这里则是设置生成的键值对的过期时间（作为缓存确实得有过期时间）
         *  entryTtl(Duration.ofSeconds(120))
         *  这里是禁止插入空值的键值对
         *  disableCachingNullValues()
         */
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(120))
                .disableCachingNullValues()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Object.class)));
 
        return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build();
 
    }
}